package tbpay

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"

	"gitee.com/liuxuezhan/ar-platform/admin-api/internal/pay/base"
	"gitee.com/liuxuezhan/ar-platform/admin-api/pkg/emun"
)

type Factory struct {
}

func (p *Factory) CreatePay(config base.Config) base.Payment {
	return &TBPay{
		Url:        config.Url,
		MerchantId: config.MerchantId,
		SecretKey:  config.SecretKey,
		ReturnUrl:  config.ReturnUrl,
		NotifyUrl:  config.NotifyUrl,
	}
}

type TBPay struct {
	Url        string `json:"url"`         // 网关//
	MerchantId string `json:"merchant_id"` // 商户账号
	SecretKey  string `json:"secret_key"`  // 代收秘钥
	ReturnUrl  string `json:"return_url"`
	NotifyUrl  string `json:"notify_url"`
}

// Response represents the structure of the response from the API
type Response struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
	Data    any    `json:"data"`
}

func (t *TBPay) Withdraw(ctx context.Context, req map[string]any) (base.WithdrawRes, error) {
	// 测试用户
	// account number : 19000200004538
	// IFSC ： FDRL0001900
	// 名字  : MAHAMMAD RAFEEQ A
	// 银行名字 : Bank federal

	params := map[string]interface{}{
		"merchantNo":  t.MerchantId,
		"orderAmount": fmt.Sprintf("%.2f", req["Order"].(map[string]any)["RealAmount"]),
		"payType":     1,
		"orderNo":     req["Order"].(map[string]any)["OrderNo"],
		"notifyUrl":   t.NotifyUrl,
		"signType":    "AES",
		"version":     "1.0",
		// "accNo":       "19000200004538",
		// "accName":     "MAHAMMAD RAFEEQ A",
		// "accType":     "IND00055",
	}

	// 判断提现方式
	switch req["Order"].(map[string]any)["ChannelType"].(int32) {
	case 1: // 银行卡
		params["accNo"] = req["Order"].(map[string]any)["UserBank"].(map[string]any)["CardNumber"]
		params["accName"] = req["Order"].(map[string]any)["UserBank"].(map[string]any)["UserName"]
		params["accType"] = "IND00055"
		// params["transferCode"] = req["UserBank"].(map[string]any)["IfcsCode"]
	case 4: // PIX
		params["accNo"] = req["Order"].(map[string]any)["UserPixWallets"].(map[string]any)["Account"]
		params["accName"] = req["Order"].(map[string]any)["UserPixWallets"].(map[string]any)["Username"]
		params["accType"] = emun.GetUserPixWalletNameByType(int(req["Order"].(map[string]any)["UserPixWallets"].(map[string]any)["WalletType"].(int32)))
	case 5: // USDT
		params["accNo"] = req["Order"].(map[string]any)["UserUsdtWallets"].(map[string]any)["Address"]
		params["accName"] = "USDT"
		params["accType"] = "USDT"
	}
	sign, err := t.WithdrawSign(params)
	if err != nil {
		return base.WithdrawRes{}, err
	}
	params["sign"] = sign

	payUrl := t.Url + "/apiOrder/withdraw"
	response, err := t.send(ctx, payUrl, params, "post")
	if err != nil {
		return base.WithdrawRes{}, err
	}

	return base.WithdrawRes{
		OrderSn:      req["Order"].(map[string]any)["OrderNo"].(string),
		ThirdOrderSn: response.Data.(map[string]any)["orderId"].(string),
	}, nil
}

func (t *TBPay) WithdrawSign(params map[string]interface{}) (string, error) {
	encrypt, err := EncryptData(params, []byte(t.SecretKey))
	if err != nil {
		return "", err
	}
	return encrypt, nil
}

// 发送请求，处理返回数据
func (t *TBPay) send(ctx context.Context, payUrl string, data map[string]interface{}, method string) (Response, error) {
	resp, err := base.SendJson(ctx, payUrl, data, method)
	if err != nil {
		return Response{}, err
	}

	// Parse the JSON response
	var response Response
	err = json.Unmarshal([]byte(resp), &response)
	if err != nil {
		return Response{}, err
	}

	// 返回结果处理
	if response.Code != 200 {
		return Response{}, errors.New(response.Message)
	}

	return response, nil
}
